/*
 * CFJ-3000 - Phone system.
 *
 * (c) 2007 Cleiber Marques
 * (c) 2007 Filipe Medeiros
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include "cfj.h"

/* Function: open_soundcard
   let's open a sound device in mode O_RDWR,returns -1 if failed.*/
int open_soundcard()
{
	int param;
	if ((audiofd = open(AUDIO_DEV, O_RDWR, 0)) == -1)  
	{ 
		perror("Can not open audio device!\n"); 
		return(-1);
	} 

	/* set the sound buffer lenght */
	  
	param=AUDIO_BUFF_SIZE;
      
	if (ioctl(audiofd, SNDCTL_DSP_GETBLKSIZE, &param) == -1) 
	{ 
		perror("I can not set fragment size on this device.\n");  
		return(-1);
	}  

	/* set the sample type to 1ogarithmic mu-law audio encoding */

	param = AFMT_U8;  
	if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &param)==-1)  
	{ 
		perror("I can not sample type on this device.\n");  
		return(-1);  
	}  

	if (param != AFMT_U8)  
	{  
		perror("Can not set desired sample type on device.\n");  
		return(-1);  
	} 

	/* set the card to mono mode */

	param = 0;
	if (ioctl(audiofd, SNDCTL_DSP_STEREO, &param)==-1)
	{ 
		perror("I can not set mono on this device.\n");  
		return(-1);  
	}  
	if (param != 0)  
	{
		perror("This device doesn't support mono mode!\n");  
		return(-1);  
	} 
		
	/* set the sampling frequency */
	param = 8000;
	if (ioctl(audiofd, SNDCTL_DSP_SPEED, &param)==-1)  
	{ 
		perror("I can not set rate on this device.\n");  
		return(-1);  
	} 
	if (param != 8000)
        {
	    printf("This device doesn't support 8000Hz sampling frequency.\n"
	     "This device can only handle %dHz frequency.\n", param);
        }	
	if(ioctl(audiofd,SNDCTL_DSP_GETCAPS,&param)==-1)
	{
		perror("I can not check capabilities of this device.\n");  
		return(-1);  
	}
	if(!(param&DSP_CAP_DUPLEX))
	{
		perror("I need a full duplex card, sorry.\n");  
		return(-1);  
	}
	return(audiofd);
}

/* Function: read_from_soundcard    
   this function reads from audio card on given descriptor.*/	
int read_from_soundcard(int audiofd, u_char *audio_buffer, int count)
{
   int len;  

	if ((len = read(audiofd, audio_buffer, count)) == -1)  
	{  
		perror("Cannot read from audio device!\n");  
		return(-1);
	}
	return (len);
}

/* Function: write_to_soundcard               
   this function writes to audio card on given descriptor.*/
int write_to_soundcard(int audiofd, u_char *audio_buffer, int count)
{
   int len;  
	
	if ((len = write(audiofd, audio_buffer, count)) == -1)  
	{  
		perror( "Cannot write to audio device!\n");  
		return(-1);
	}
	return (len);
}

/* Function: close_soundcard
   this function close the soundcard.*/
int close_soundcard(int audiofd)
{
	if (ioctl(audiofd, SNDCTL_DSP_SYNC, 0) < 0) 
	{
		perror("Can not flush device!\n");
		return(-1);
	}
	if (close(audiofd) < 0)
	{
		perror("Can not close sound device!\n");
		return(-1);
	}
	return(1);
}

